import {
    _decorator,
    Component,
    Node,
    instantiate,
    Vec2,
    UITransform,
    Vec3,
    v3,
    JsonAsset,
    SpriteFrame,
    Sprite,
    Label,
    Prefab,
    v2,
    path,
} from "cc";
import { DEBUG } from "cc/env";
import Toast from "../../core/component/Toast";
import { Engine } from "../../core/Engine";
import { uiManager } from "../../core/manager/UIManager";
import { getNowTime } from "../../core/utils/utils";
import { ResourceBar } from "../component/ResourceBar";
import { dataManager } from "../data/DataManager";
import { BELONG_TYPE, CityInfoData, MAP_CELL_NUM, MAP_CELL_SIZE } from "../data/MapData";
import { DispatchArmyInfo } from "../data/SoldierData";
import { DATA_NAME, DATA_OPTION, DATA_PROPERTY, EVENT_NAME, GAME_DATA, UI_NAME } from "../GameConstant";
import { gameRecordManager } from "../manager/GameRecordManager";
import { City } from "./City";
import { DispatchArmyItem } from "./DispatchArmyItem";
import { WorldArmy } from "./WorldArmy";
const { ccclass, property } = _decorator;

@ccclass("MapView")
export class MapView extends Component {
    @property({ type: Node, displayName: "背景容器" })
    mapBgContent!: Node;

    @property({ type: Node, displayName: "城池容器" })
    mapCityContent!: Node;

    @property({ type: Node, displayName: "士兵容器" })
    mapSoldierContent!: Node;

    // 之后城池和士兵修改为对象池的形式
    @property({ type: Prefab, displayName: "城池预制" })
    cityPrefab!: Prefab;

    @property({ type: Prefab, displayName: "士兵预制" })
    soldierPrefab!: Prefab;

    @property({ type: ResourceBar, displayName: "资源容器" })
    resourceBar!: ResourceBar;

    @property({ type: Node, displayName: "出征队列" })
    dispatchArmyList!: Node;

    @property({ type: Node, displayName: "敌方出征队列" })
    enemyDispatchArmyList!: Node;

    @property({ type: ResourceBar, displayName: "资源容器" })
    enemyResourceBar!: ResourceBar;

    @property({ type: Node, displayName: "地图蒙板" })
    mask_map!: Node;

    @property({ type: Node, displayName: "选择目标城池" })
    chooseTargetCity!: Node;
    @property({ type: Node, displayName: "选择出兵城池" })
    chooseFromCity!: Node;

    private currentSelectedCity: Node | undefined; // 当前选中城池

    onLoad() {
        Engine.eventManager.on(EVENT_NAME.WORLD_MAP_INITED, this.initMapView, this);
        Engine.eventManager.on(
            DATA_OPTION.UPDATE + DATA_NAME.PLAYER_DATA + DATA_PROPERTY.materialS,
            () => {
                this.resourceBar.setData();
            },
            this
        );
        Engine.eventManager.on(
            DATA_OPTION.UPDATE + DATA_NAME.PLAYER_DATA + DATA_PROPERTY.soldiers,
            () => {
                this.resourceBar.setData();
            },
            this
        );

        Engine.eventManager.on(
            EVENT_NAME.READY_ATTACK_CITY,
            (cityId: string, belong: BELONG_TYPE) => {
                dataManager.dataMap.readyBattleCity = {
                    cityId: cityId,
                    belong: belong,
                };
                this.mask_map.active = true;
                this.chooseFromCity.active = false;
                this.chooseTargetCity.active = true;
            },
            this
        );
        Engine.eventManager.on(
            EVENT_NAME.READY_BE_ATTACK_CITY,
            (cityId: string, belong: BELONG_TYPE) => {
                dataManager.dataMap.readyBattleCity = {
                    cityId: cityId,
                    belong: belong,
                };
                this.mask_map.active = true;
                this.chooseFromCity.active = true;
                this.chooseTargetCity.active = false;
            },
            this
        );

        Engine.eventManager.on(
            EVENT_NAME.START_DISPATCH_ARMY,
            (armyInfo: DispatchArmyInfo) => {
                if (armyInfo.belong === BELONG_TYPE.SELF_SIDE) {
                    dataManager.dataMap.readyBattleCity = undefined;
                    this.mask_map.active = false;
                    this.chooseFromCity.active = false;
                    this.chooseTargetCity.active = false;
                }
                // 添加到出征列表
                this.addDispatchArmyItem(armyInfo.armyId, armyInfo);
                // 世界移动形象
                this.addSoldierArmy(armyInfo.armyId, armyInfo);
            },
            this
        );

        Engine.eventManager.on(
            EVENT_NAME.GAME_OVER,
            (isWIn: boolean) => {
                if (isWIn) {
                    uiManager.show(UI_NAME.COMMON_ALERT, {
                        title: "",
                        content: "战斗胜利，恭喜！",
                        okLabel: "确定",
                    });
                } else {
                    uiManager.show(UI_NAME.COMMON_ALERT, {
                        title: "",
                        content: "战斗失败，再接再励！",
                        okLabel: "确定",
                    });
                }
            },
            this
        );

        // TODO 敌方资源调试
        Engine.eventManager.on(
            DATA_OPTION.UPDATE + DATA_NAME.ENEMY_DATA + DATA_PROPERTY.materialS,
            () => {
                this.enemyResourceBar.setData();
            },
            this
        );
        Engine.eventManager.on(
            DATA_OPTION.UPDATE + DATA_NAME.ENEMY_DATA + DATA_PROPERTY.soldiers,
            () => {
                this.enemyResourceBar.setData();
            },
            this
        );
    }
    start() {
        if (dataManager.dataMap.isInit()) {
            this.initMapView();
        }
    }

    initMapView() {
        // 背景
        for (let i = 0; i < MAP_CELL_NUM.tileRow; i++) {
            for (let j = 0; j < MAP_CELL_NUM.tileColno; j++) {
                const bgIdx = i * MAP_CELL_NUM.tileColno + j;
                const blockName = i + "-" + j;
                let bgBlockNode = this.mapBgContent.children[bgIdx];
                if (!bgBlockNode) {
                    bgBlockNode = instantiate(this.mapBgContent.children[0]);
                    bgBlockNode.parent = this.mapBgContent;
                }
                bgBlockNode.position = v3(j * MAP_CELL_SIZE.tileWidth, i * MAP_CELL_SIZE.tileHeight, 0);
                if (DEBUG) {
                    bgBlockNode.getChildByName("block_num")!.getComponent(Label)!.string = blockName;
                }
                const resName = dataManager.dataMap.bgBlockList[blockName]
                    ? dataManager.dataMap.bgBlockList[blockName]
                    : "block" + (MAP_CELL_NUM.tileRow - i) + "_" + (j + 1);
                Engine.resManager
                    .loadPath<SpriteFrame>("textures/map/" + resName + "/spriteFrame")
                    .then((sprFame: SpriteFrame) => {
                        bgBlockNode.getComponent(Sprite)!.spriteFrame = sprFame;
                        dataManager.dataMap.bgBlockList[blockName] = sprFame!.name;
                    });
            }
        }

        // 城池
        for (const cityId in dataManager.dataMap.terrainList) {
            this.addCity(cityId);
        }

        // 出征列表
        this.initArmyList();
        // 玩家资源
        this.resourceBar.setData();

        this.enemyResourceBar.setData();
    }

    // 出征列表
    private async initArmyList() {
        let armyIdx = 0;
        for (const armyId in dataManager.dataPlayer.dispatchingArmyList) {
            const armyData = dataManager.dataPlayer.dispatchingArmyList[armyId]!;
            // 出征队列
            this.addDispatchArmyItem(armyId, armyData, armyIdx);
            // 添加士兵形象到地图
            this.addSoldierArmy(armyId, armyData);
            armyIdx += 1;
        }

        armyIdx = 0;
        for (const armyId in dataManager.dataEnemy.dispatchingArmyList) {
            const armyData = dataManager.dataEnemy.dispatchingArmyList[armyId]!;
            // 出征队列
            this.addDispatchArmyItem(armyId, armyData, armyIdx);
            // 添加士兵形象到地图
            this.addSoldierArmy(armyId, armyData);
            armyIdx += 1;
        }
    }

    private addCity(cityId: string) {
        const cityNode = instantiate(this.cityPrefab);
        cityNode.parent = this.mapCityContent;
        cityNode.getComponent(City)!.setData(cityId);
    }

    // 出征队列
    private addDispatchArmyItem(armyId: string, armyData: DispatchArmyInfo, armyIdx?: number) {
        const listContainer =
            armyData.belong === BELONG_TYPE.SELF_SIDE ? this.dispatchArmyList : this.enemyDispatchArmyList;
        if (!armyIdx) {
            if (armyData.belong === BELONG_TYPE.SELF_SIDE) {
                armyIdx = Object.keys(dataManager.dataPlayer.dispatchingArmyList).length - 1;
            } else {
                armyIdx = Object.keys(dataManager.dataEnemy.dispatchingArmyList).length - 1;
            }
        }

        let armyItemNode = listContainer.children[armyIdx];
        if (!armyItemNode) {
            armyItemNode = instantiate(listContainer.children[0]);
            armyItemNode.parent = listContainer;
        }
        armyItemNode.active = true;
        armyItemNode.getComponent(DispatchArmyItem)!.setData(armyId, armyData);
    }

    // 移动的士兵形象
    private addSoldierArmy(armyId: string, armyData: DispatchArmyInfo) {
        const startCityDetail = dataManager.dataMap.getCityDetail(armyData.fromCityId);
        const toCityDetail = dataManager.dataMap.getCityDetail(armyData.toCityId);
        if (startCityDetail?.belong === toCityDetail?.belong) {
            // TODO 派遣兵不展示 观察攻击兵调用
            return;
        }
        const soldierNode = instantiate(this.soldierPrefab);
        soldierNode.parent = this.mapSoldierContent;
        soldierNode.getComponent(WorldArmy)!.setData(armyId, armyData);
    }

    // 取消出征城市选择
    private cancelChooseBattleCity() {
        dataManager.dataMap.readyBattleCity = undefined;
        this.mask_map.active = false;
        this.chooseFromCity.active = false;
        this.chooseTargetCity.active = false;
    }

    // 对战记录
    private showBattleLog() {
        uiManager.show(UI_NAME.BATTLE_LOG_PANEL);
    }

    private clearStore() {
        gameRecordManager.resetGameData();
    }

    private statGame() {
        // this.army
    }

    private getPath(startVertex: string, targetVertex: string) {
        const pathVertex: string[] = [targetVertex];
        // 从后向前 遍历顶点 找出路径
        const toVertexPaths = dataManager.dataMap.dijks!.findPath(startVertex);
        let currentVertex = targetVertex;
        while (toVertexPaths[currentVertex]) {
            currentVertex = toVertexPaths[currentVertex];
            pathVertex.push(currentVertex);
        }
        pathVertex.push(startVertex);
        const paths = pathVertex.reverse(); // [...new Set(pathVertex)]
        return paths;
    }

    private findPath() {
        const paths = this.getPath("45", "67");
        console.log(paths);
        // Engine.eventManager.emit(EVENT_NAME.GAME_OVER, false);
    }

    private findPath2() {
        Engine.eventManager.emit(EVENT_NAME.GAME_OVER, false);
        // const paths = this.getPath("26", "20");
        // console.log(paths);
    }
}
